package com.qixiaobao.servicefee.service.impl;

import com.qixiaobao.common.core.domain.model.LoginUser;
import com.qixiaobao.common.core.redis.RedisLock;
import com.qixiaobao.common.exception.UtilException;
import com.qixiaobao.common.utils.SecurityUtils;
import com.qixiaobao.common.utils.StringUtils;
import com.qixiaobao.common.utils.easyExcel.EasyExcelUtil;
import com.qixiaobao.servicefee.domain.HandlingFee;
import com.qixiaobao.servicefee.domain.HandlingFeeCharge;
import com.qixiaobao.servicefee.domain.dto.HandlingFeeDTO;
import com.qixiaobao.servicefee.domain.dto.HandlingFeeDetailDTO;
import com.qixiaobao.servicefee.domain.dto.WaitSettlementDTO;
import com.qixiaobao.servicefee.domain.vo.HandlingFeeDetailVO;
import com.qixiaobao.servicefee.domain.vo.HandlingFeeWaitSettlementVO;
import com.qixiaobao.servicefee.mapper.ServiceFeeMapper;
import com.qixiaobao.servicefee.service.IServiceFeeService;
import com.qixiaobao.nondirect.invoice.domain.domain.*;
import com.qixiaobao.system.domain.*;
import com.qixiaobao.system.domain.dto.PersonDTO;
import com.qixiaobao.system.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @Description 手续费管理  业务层实现
 * @Author yangxm
 * @Date 2025/6/24 10:11
 */
@Slf4j
@Service
public class ServiceFeeServiceImpl implements IServiceFeeService {

    @Autowired
    private ServiceFeeMapper serviceFeeMapper;
    @Autowired
    private DictMapper dictMapper;
    @Autowired
    private SlaveUserMapper slaveUserMapper;
    @Autowired
    private SupplyMapper supplyMapper;
    @Autowired
    private ChargeMapper chargeMapper;
    @Autowired
    private RedisLock redisLock;
    @Autowired
    private PersonMapper personMapper;

    private static final BigDecimal ONE_HUNDRED = new BigDecimal(100);

    /**
     * @Description 查询待结算列表
     * @Author yangxm
     * @Date 2025/6/24 10:12
     * @param waitSettlementDTO
     * @return java.util.List<com.qixiaobao.servicefee.domain.vo.WaitSettlementVO>
     */
    @Override
    public List<HandlingFeeWaitSettlementVO> selectWaitSettlementList(WaitSettlementDTO waitSettlementDTO) {
        log.info("查询待结算列表---------------------");
        long begin = System.currentTimeMillis();
        List<HandlingFeeWaitSettlementVO> list = serviceFeeMapper.selectWaitSettlementList(waitSettlementDTO);
        log.info("查询待结算sql列表，耗时：{}ms", System.currentTimeMillis() - begin);
        if (StringUtils.isNotEmpty(list)){
            List<Dict> dictList = dictMapper.selectDictList();
            Map<String, Map<String, String>> dictMap = new ConcurrentHashMap<>();
            if (dictList != null && !dictList.isEmpty()) {
                dictMap = dictList.stream().filter(c -> c.getVal() != null).collect(Collectors.groupingBy(Dict::getType, Collectors.toMap(Dict::getK, Dict::getVal)));
            }
            Map<String, String> insuretypeMap = dictMap.get("insuretype");
            Map<String, String> insurePeriodMap = dictMap.get("insureperiod");
            Map<String, String> extensionMap = dictMap.get("extension");
            Map<String, String> mealnameMap = dictMap.get("mealname");
            Map<String, String> maimRatioMap = dictMap.get("maimRatio");
            Map<String, String> jobtypeMap = dictMap.get("jobtype");

            Map<Long, String> usernameMap = slaveUserMapper.selectUsernameList().stream()
                    .collect(Collectors.toMap(SlaveUser::getId, SlaveUser::getUsername));

            HashMap<String, String> insureFromMap = new HashMap<>();
            insureFromMap.put("0", "增减员");
            insureFromMap.put("1", "投保");

            HandlingFeeWaitSettlementVO waitSettlementVO;
            for (int i = 0; i < list.size(); i++) {
                waitSettlementVO = list.get(i);
                waitSettlementVO.setIndex(i + 1);
                waitSettlementVO.setInsureTypeVal(insuretypeMap.get(waitSettlementVO.getInsureType()));
                waitSettlementVO.setInsurePeriodVal(insurePeriodMap.get(waitSettlementVO.getInsurePeriod()));
                waitSettlementVO.setExtensionVal(extensionMap.get(waitSettlementVO.getExtension()));
                waitSettlementVO.setMealNameVal(mealnameMap.get(waitSettlementVO.getMealName()));
                waitSettlementVO.setMaimRatioVal(maimRatioMap.get(waitSettlementVO.getMaimRatio()));
                waitSettlementVO.setJobTypeVal(jobtypeMap.get(waitSettlementVO.getJobType()));
                waitSettlementVO.setServiceName(usernameMap.getOrDefault(waitSettlementVO.getServiceId(), ""));
                waitSettlementVO.setInsureFromVal(insureFromMap.get(waitSettlementVO.getInsureFrom()));
                waitSettlementVO.setInsurePerson("增员:" + waitSettlementVO.getAddNum() + ";减员:" + waitSettlementVO.getMinusNum());
                waitSettlementVO.setAbandonFlagVal(waitSettlementVO.getAbandonFlag() == 1 ? "是" : "否");
                waitSettlementVO.setInsureFeeSettleStatusVal("1".equals(waitSettlementVO.getInsureFeeSettleStatus()) ? "已结算" : "待结算");
                //手续费总计（公式：保险费总计/保费系数*手续费率）
                waitSettlementVO.setHandlingFee(waitSettlementVO.getCopeInsureFee().divide(waitSettlementVO.getInsureFeeFactor(), 4, RoundingMode.HALF_UP).multiply(waitSettlementVO.getServiceRate()).setScale(2, RoundingMode.HALF_UP));
            }
        }
        log.info("查询待结算列表，耗时：{}ms", System.currentTimeMillis() - begin);
        return list;
    }

    /**
     * @Description 查询待结算 保险费总计、手续费总计
     * @Author yangxm
     * @Date 2025/6/24 13:36
     * @param waitSettlementDTO
     * @return java.util.Map<java.lang.String,java.math.BigDecimal>
     */
    @Override
    public Map<String, BigDecimal> selectWaitMoneyTotal(WaitSettlementDTO waitSettlementDTO) {
        log.info("查询待结算费用总计---------------------");
        long begin = System.currentTimeMillis();
        List<HandlingFeeWaitSettlementVO> list = serviceFeeMapper.selectWaitMoneyTotalList(waitSettlementDTO);
        log.info("查询待结算费用总计sql列表，耗时：{}ms", System.currentTimeMillis() - begin);
        Map<String, BigDecimal> map = new HashMap<>();
        if (StringUtils.isNotEmpty(list)){
            HandlingFeeWaitSettlementVO waitSettlementVO;
            for (int i = 0; i < list.size(); i++) {
                waitSettlementVO = list.get(i);
                //手续费总计（公式：保险费总计/保费系数*手续费率）
                waitSettlementVO.setHandlingFee(waitSettlementVO.getCopeInsureFee().divide(waitSettlementVO.getInsureFeeFactor(), 4, RoundingMode.HALF_UP).multiply(waitSettlementVO.getServiceRate()).setScale(2, RoundingMode.HALF_UP));
            }
            map.put("insureFeeTotal", list.stream().map(HandlingFeeWaitSettlementVO::getCopeInsureFee).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
            map.put("handlingFeeTotal", list.stream().map(HandlingFeeWaitSettlementVO::getHandlingFee).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add));
        }
        return map;
    }

    /**
     * @Description 查询待结算人员列表
     * @Author yangxm
     * @Date 2025/6/24 13:36
     * @param chargeId
     * @return java.util.List<com.qixiaobao.nondirect.invoice.domain.domain.Person>
     */
    @Override
    public List<Person> selectWaitPersonList(Long chargeId) {
        return serviceFeeMapper.selectWaitPersonList(chargeId);
    }

    /**
     * @Description 待结算 - 结算功能
     * @Author yangxm
     * @Date 2025/6/24 14:14
     * @param handlingFee
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int settleForWait(HandlingFee handlingFee) {
        log.info("待结算 - 结算功能，参数：{}---------------------", handlingFee);
        long begin = System.currentTimeMillis();
        List<Long> supplyIdList = handlingFee.getSupplyIdList();
        if (StringUtils.isEmpty(supplyIdList)){
            throw new UtilException("请先选择供应商！");
        }
        List<Supply> supplyList = supplyMapper.selectSupplyListByIdList(supplyIdList);
        if (StringUtils.isEmpty(supplyList)){
            throw new UtilException("未查询到供应商！");
        }
        //供应商校验
        checkSupply(supplyList);
        //供应商校验完成
        Supply supplyer = supplyList.get(0);
        handlingFee.setSupplyId(supplyer.getId());
        //供应商全称
        handlingFee.setSupplyName(supplyer.getSupplyName());
        //保费系数
        handlingFee.setInsureFeeFactor(supplyer.getInsureFeeFactor());
        //手续费税率
        handlingFee.setHandlingTaxRate(supplyer.getServiceRate() == null ? BigDecimal.ZERO : supplyer.getServiceRate());
        //经纪结算费率
        handlingFee.setBrokerageSettleRatio(supplyer.getBrokerageSettleRatio() == null ? BigDecimal.ZERO : supplyer.getBrokerageSettleRatio());
        //手续费发票类型
        handlingFee.setProcedureFeeInvoiceType(supplyer.getProcedureFeeInvoiceType());
        //手续费发票状态默认为：未开票，若手续费发票类型为不开发票，则手续费发票状态为不开票
        handlingFee.setHandlingFeeInvoiceState("1");
        if ("3".equals(supplyer.getProcedureFeeInvoiceType())){
            handlingFee.setHandlingFeeInvoiceState("0");
        }
        //需要结算的费用ID集合
        List<Long> chargeIds = handlingFee.getChargeIdList();
        if (!Optional.ofNullable(chargeIds).isPresent() || chargeIds.size() < 1) {
            throw new IllegalArgumentException("费用列表不能为空");
        }
        String handleFeeMonth = handlingFee.getHandleFeeMonth();
        if (!Optional.ofNullable(handleFeeMonth).isPresent() || StringUtils.isBlank(handleFeeMonth = handleFeeMonth.trim())) {
            throw new IllegalArgumentException("手续费周期不能为空");
        }
        handlingFee.setHandleFeeMonth(handleFeeMonth);
        //校验奖励手续费费率
        BigDecimal rewardHandlingFeeRate = handlingFee.getRewardHandlingFeeRate();
        if (rewardHandlingFeeRate == null){
            throw new IllegalArgumentException("奖励手续费费率不能为空");
        }
        String receiptCompany = handlingFee.getReceiptCompany();
        if (StringUtils.isBlank(receiptCompany)) {
            throw new IllegalArgumentException("手续费账户不能为空");
        }
        handlingFee.setReceiptCompany(receiptCompany);
        handlingFee.setHandlingFeeStatus("0");
        serviceFeeMapper.insertHandlingFee(handlingFee);
        int addNum = 0;
        int minusNum = 0;
        BigDecimal insureFeeTotal = BigDecimal.ZERO;
        BigDecimal handlingFeeTotal = BigDecimal.ZERO;

        List<Charge> chargeList = chargeMapper.selectChargeListByIdList(chargeIds);
        Charge charge;
        for (int i = 0; i < chargeList.size(); i++) {
            charge = chargeList.get(i);
            String lock=String.format("lcok:HandlingFee:chargeid:%d",charge.getId());
            if(!redisLock.tryLock(lock,60)){
                log.error("该费用正在结算手续费，请稍后重试");
                throw new UtilException("该费用正在结算手续费，请稍后重试");
            }
            if (!"0".equals(charge.getHandlingFeeSettle())) {
                throw new UtilException("有已经结算的费用，不能重复结算，请刷新页面重新结算！");
            }
            addNum += Optional.ofNullable(charge.getAddNum()).orElse(0);
            minusNum += Optional.ofNullable(charge.getMinusNum()).orElse(0);
            //保费总计
            insureFeeTotal = insureFeeTotal.add(Optional.ofNullable(charge.getCopeInsureFee()).orElse(BigDecimal.ZERO));
            //手续费总计=保险费总计/保费系数*手续费率
            if (charge.getCopeInsureFee() != null){
                handlingFeeTotal = handlingFeeTotal.add(charge.getCopeInsureFee().divide(handlingFee.getInsureFeeFactor(), 4, RoundingMode.HALF_UP).multiply(charge.getServiceRate()).setScale(2, RoundingMode.HALF_UP));
            }
            HandlingFeeCharge handlingFeeCharge = new HandlingFeeCharge();
            handlingFeeCharge.setHandlingFeeId(handlingFee.getId());
            handlingFeeCharge.setChargeId(charge.getId());
            serviceFeeMapper.insertHandlingFeeCharge(handlingFeeCharge);

            charge.setHandlingFeeSettle("1");
            chargeMapper.updateHandlingFeeSettle(charge);
        }
        handlingFee.setAddNum(addNum);
        handlingFee.setMinusNum(minusNum);
        handlingFee.setInsureFeeTotal(insureFeeTotal);
        handlingFee.setHandlingFeeTotal(handlingFeeTotal.setScale(2, RoundingMode.HALF_UP));
        int row = serviceFeeMapper.updateHandlingFee(handlingFee);
        log.info("手续费结算完成，耗时：{}ms", System.currentTimeMillis() - begin);
        return row;
    }

    /**
     * @Description 待结算 - 一键结算功能
     * @Author yangxm
     * @Date 2025/6/24 16:06
     * @param waitSettlementDTO
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int settleAllForWait(WaitSettlementDTO waitSettlementDTO) {
        log.info("待结算 - 一键结算功能-----------参数：{}", waitSettlementDTO);
        long begin = System.currentTimeMillis();
        if (waitSettlementDTO == null){
            throw new UtilException("参数不能为空");
        }
        if (StringUtils.isEmpty(waitSettlementDTO.getSupplyIdList())){
            throw new UtilException("供应商简称不能为空");
        }
        if (StringUtils.isBlank(waitSettlementDTO.getHandleFeeMonth())){
            throw new UtilException("手续费周期不能为空");
        }
        if (StringUtils.isBlank(waitSettlementDTO.getReceiptCompany())){
            throw new UtilException("手续费账户不能为空");
        }
        if (waitSettlementDTO.getRewardHandlingFeeRate() == null){
            throw new UtilException("奖励手续费费率不能为空");
        }
        //根据筛选条件，查询待结算信息
        List<HandlingFeeWaitSettlementVO> waitSettlementVOList = selectWaitSettlementList(waitSettlementDTO);
        if (StringUtils.isNotEmpty(waitSettlementVOList)){
            throw new UtilException("未查询到需要结算的手续费!");
        }
        List<Long> chargeIdList = waitSettlementVOList.stream().map(HandlingFeeWaitSettlementVO::getChargeId).distinct().collect(Collectors.toList());
        HandlingFee handlingFee = new HandlingFee();
        handlingFee.setSupplyIdList(waitSettlementDTO.getSupplyIdList());
        handlingFee.setHandleFeeMonth(waitSettlementDTO.getHandleFeeMonth());
        handlingFee.setChargeIdList(chargeIdList);
        handlingFee.setReceiptCompany(waitSettlementDTO.getReceiptCompany());
        handlingFee.setRewardHandlingFeeRate(waitSettlementDTO.getRewardHandlingFeeRate());
        int row = settleForWait(handlingFee);
        log.info("待结算 - 一键结算功能完成，耗时：{}ms：", System.currentTimeMillis() - begin);
        return row;
    }

    /**
     * @Description 待收款、已结算 列表
     * @Author yangxm
     * @Date 2025/6/25 11:39
     * @param handlingFeeDTO
     * @return java.util.List<com.qixiaobao.servicefee.domain.HandlingFee>
     */
    @Override
    public List<HandlingFee> selectHandlingFeeList(HandlingFeeDTO handlingFeeDTO) {
        log.info("待收款、已结算 列表-----------参数：{}", handlingFeeDTO);
        long begin = System.currentTimeMillis();
        List<HandlingFee> list = serviceFeeMapper.selectHandlingFeeList(handlingFeeDTO);
        log.info("待收款、已结算 列表sql完成，耗时：{}ms：", System.currentTimeMillis() - begin);
        if (StringUtils.isNotEmpty(list)){
            List<Dict> dictList = dictMapper.selectDictList();
            Map<String, Map<String, String>> dictMap = new ConcurrentHashMap<>();
            if (dictList != null && !dictList.isEmpty()) {
                dictMap = dictList.stream().filter(c -> c.getVal() != null).collect(Collectors.groupingBy(Dict::getType, Collectors.toMap(Dict::getK, Dict::getVal)));
            }
            Map<String, String> receiptCompanyMap = dictMap.get("receiptCompany");
            Map<String, String> procedureFeeInvoiceTypeMap = dictMap.get("procedureFeeInvoiceType");

            HandlingFee item;
            //奖励手续费率
            BigDecimal rewardHandlingFeeRate;
            //手续费说率
            BigDecimal handlingTaxRate;
            //经纪结算费率
            BigDecimal brokerageSettleRatio;
            for (int i = 0; i < list.size(); i++) {
                item = list.get(i);
                item = list.get(i);
                item.setReceiptCompanyVal(receiptCompanyMap.get(item.getReceiptCompany()));
                //奖励手续费率，百分比转换为小数
                rewardHandlingFeeRate = item.getRewardHandlingFeeRate().divide(ONE_HUNDRED, 4, RoundingMode.HALF_UP);
                //奖励手续费:保险费总计/保费系数*奖励手续费率
                item.setRewardHandlingFeeTotal(item.getInsureFeeTotal().divide(item.getInsureFeeFactor(), 2, RoundingMode.HALF_UP).multiply(rewardHandlingFeeRate).setScale(2, RoundingMode.HALF_UP));
                //手续费税率，百分比转换为小数
                handlingTaxRate = item.getHandlingTaxRate().divide(ONE_HUNDRED, 4, RoundingMode.HALF_UP);
                //手续费税后总计:（手续费总计+奖励手续费）*（1-手续费税率）
                item.setRateHandlingFeeTotal((item.getHandlingFeeTotal().add(item.getRewardHandlingFeeTotal())).multiply(BigDecimal.ONE.subtract(handlingTaxRate)).setScale(2, RoundingMode.HALF_UP));
                //经纪结算费率，百分比转换为小数
                brokerageSettleRatio = item.getBrokerageSettleRatio().divide(ONE_HUNDRED, 4, RoundingMode.HALF_UP);
                //手续费实收金额: 手续费税后总计*（1-经纪结算费率）
                item.setActualHandlingFeeTotal(item.getRateHandlingFeeTotal().multiply(BigDecimal.ONE.subtract(brokerageSettleRatio)).setScale(2, RoundingMode.HALF_UP));
                //手续费发票类型
                item.setProcedureFeeInvoiceTypeVal(procedureFeeInvoiceTypeMap.get(item.getProcedureFeeInvoiceType()));
                //手续费发票金额:如不开票则为0，默认等于手续费实收金额
                if ("3".equals(item.getProcedureFeeInvoiceType())) {
                    item.setHandlingFeeInvoiceTotal(BigDecimal.ZERO);
                } else {
                    item.setHandlingFeeInvoiceTotal(item.getHandlingFeeInvoiceTotal() == null ? item.getActualHandlingFeeTotal() : item.getHandlingFeeInvoiceTotal());
                }
                item.setHandlingFeeInvoiceStateVal("0".equals(item.getHandlingFeeInvoiceState()) ? "不开票" : "1".equals(item.getHandlingFeeInvoiceState()) ? "未开票" : "已开票");
                item.setFinancePayeeStateVal("1".equals(item.getFinancePayeeState()) ? "是" : "否");
            }
        }
        return null;
    }

    /**
     * @Description 待收款、已结算 详情列表
     * @Author yangxm
     * @Date 2025/6/25 11:39
     * @param handlingFeeDetailDTO
     * @return java.util.List<com.qixiaobao.servicefee.domain.HandlingFeeDetailVO>
     */
    @Override
    public List<HandlingFeeDetailVO> selectHandlingFeeDetailList(HandlingFeeDetailDTO handlingFeeDetailDTO) {
        log.info("待收款、已结算 详情列表-----------参数：{}", handlingFeeDetailDTO);
        long begin = System.currentTimeMillis();
        List<HandlingFeeDetailVO> list = serviceFeeMapper.selectHandlingFeeDetailList(handlingFeeDetailDTO);
        if (StringUtils.isNotEmpty(list)){
            List<Dict> dictList = dictMapper.selectDictList();
            Map<String, Map<String, String>> dictMap = new ConcurrentHashMap<>();
            if (dictList != null && !dictList.isEmpty()) {
                dictMap = dictList.stream().filter(c -> c.getVal() != null).collect(Collectors.groupingBy(Dict::getType, Collectors.toMap(Dict::getK, Dict::getVal)));
            }
            Map<String, String> mealNameMap = dictMap.getOrDefault("mealname", Collections.emptyMap());
            Map<String, String> maimRatioMap = dictMap.getOrDefault("maimRatio", Collections.emptyMap());
            Map<String, String> insureperiodMap = dictMap.getOrDefault("insureperiod", Collections.emptyMap());
            Map<String, String> insuretypeMap = dictMap.getOrDefault("insuretype", Collections.emptyMap());
            Map<String, String> jobtypeMap = dictMap.getOrDefault("jobtype", Collections.emptyMap());
            Map<String, String> deptMap = dictMap.getOrDefault("dept", Collections.emptyMap());

            Map<Long, String> usernameMap = slaveUserMapper.selectUsernameList().stream()
                    .collect(Collectors.toMap(SlaveUser::getId, SlaveUser::getUsername));

            HashMap<String, String> insureFromMap = new HashMap<>();
            insureFromMap.put("0", "增减员");
            insureFromMap.put("1", "投保");

            HandlingFeeDetailVO item;
            for (int i = 0; i < list.size(); i++) {
                item = list.get(i);
                item.setIndex(i + 1);
                item.setMealNameVal(mealNameMap.get(item.getMealName()));
                item.setInsurePeriodVal(insureperiodMap.get(item.getInsureFrom()));
                item.setJobTypeVal(jobtypeMap.get(item.getJobType()));
                item.setMaimRatioVal(maimRatioMap.get(item.getMaimRatio()));
                item.setInsureTypeVal(insuretypeMap.get(item.getInsureType()));
                item.setBelongCompanyVal(deptMap.get(item.getBelongCompany()));
                item.setSignName(usernameMap.getOrDefault(item.getSignId(), ""));
                item.setServiceName(usernameMap.getOrDefault(item.getServiceId(), ""));
                //手续费总计:保险费总计/保费系数*手续费率
                item.setHandlingFee(item.getCopeInsureFee().divide(item.getInsureFeeFactor(), 4, RoundingMode.HALF_UP).multiply(item.getServiceRate()).setScale(2, RoundingMode.HALF_UP));
                item.setAbandonFlagVal(Optional.ofNullable(item.getAbandonFlag()).orElse(0) == 1 ? "是" : "否");
                item.setInsurePerson("增员:" + item.getAddNum() + ";减员:" + item.getMinusNum());
                item.setInsureFromVal(insureFromMap.get(item.getInsureFrom()));
            }
        }
        log.info("待收款、已结算 详情列表-----------耗时：{}ms", System.currentTimeMillis() - begin);
        return list;
    }

    /**
     * @Description 待收款、已结算 导出
     * @Author yangxm
     * @Date 2025/6/25 11:39
     * @param handlingFeeDTO
     * @param response
     */
    @Override
    public void handlingFeeExport(HandlingFeeDTO handlingFeeDTO, HttpServletResponse response) {
        log.info("待收款、已结算 导出-----------参数：{}", handlingFeeDTO);
        String handlingFeeStatus = handlingFeeDTO.getHandlingFeeStatus();
        String fileName = StringUtils.equals(handlingFeeStatus, "0") ? "手续费待付款" : "手续费已结算";
        List<HandlingFee> list = selectHandlingFeeList(handlingFeeDTO);
        List<String> arrayHeaders = new ArrayList<>();
        arrayHeaders.add("序号");
        arrayHeaders.add("供应商全称");
        arrayHeaders.add("结算人数");
        arrayHeaders.add("保费系数");
        arrayHeaders.add("奖励手续费率");
        arrayHeaders.add("奖励手续费");
        arrayHeaders.add("保险费总计");
        arrayHeaders.add("手续费总计");
        arrayHeaders.add("手续费税率");
        arrayHeaders.add("手续费税后总计");
        arrayHeaders.add("经纪结算费率");
        arrayHeaders.add("操作时间");
        arrayHeaders.add("手续费收款账户");
        arrayHeaders.add("手续费实收金额");
        arrayHeaders.add("手续费周期");
        arrayHeaders.add("手续费发票类型");
        arrayHeaders.add("手续费发票金额");
        arrayHeaders.add("发票状态");
        if ("1".equals(handlingFeeStatus)){
            arrayHeaders.add("实收人");
            arrayHeaders.add("实收时间");
        }
        //导出增加备注  yangxm  2220622
        arrayHeaders.add("备注");

        //动态表头
        List<List<String>> headList = new ArrayList<>();
        String headStr;
        List<String> headArray;
        for (int i = 0; i < arrayHeaders.size(); i++) {
            headStr = arrayHeaders.get(i);
            headArray = new ArrayList<>();
            headArray.add(headStr);
            headList.add(headArray);
        }

        //动态表头的数据
        List<List<Object>> datalist = new ArrayList<>();
        List<Object> obj = null;
        HandlingFee item;
        for (int m = 0; m < list.size(); m++) {
            item = list.get(m);
            obj = new ArrayList<>();
            obj.add(m + 1);
            obj.add(item.getSupplyName());
            obj.add("增员:" + item.getAddNum() + ";减员:" + item.getMinusNum());
            obj.add(item.getInsureFeeFactor());
            obj.add(item.getRewardHandlingFeeRate());
            obj.add(item.getRewardHandlingFeeTotal());
            obj.add(item.getInsureFeeTotal());
            obj.add(item.getHandlingFeeTotal());
            obj.add(item.getHandlingTaxRate());
            obj.add(item.getRateHandlingFeeTotal());
            obj.add(item.getBrokerageSettleRatio());
            obj.add(Optional.ofNullable(item.getUpdateTime()).map(x-> DateFormatUtils.format(x, "yyyy/MM/dd HH:mm:ss")).orElse(""));
            obj.add(item.getReceiptCompanyVal());
            obj.add(item.getActualHandlingFeeTotal());
            obj.add(item.getHandleFeeMonth());
            obj.add(item.getProcedureFeeInvoiceTypeVal());
            obj.add(item.getHandlingFeeInvoiceTotal());
            obj.add(item.getHandlingFeeInvoiceStateVal());
            if ("1".equals(handlingFeeStatus)){
                obj.add(item.getFinancePayeeName());
                obj.add(Optional.ofNullable(item.getFinancePayeeTime()).map(x->DateFormatUtils.format(x, "yyyy/MM/dd HH:mm:ss")).orElse(""));
            }
            obj.add(item.getRemark());
            datalist.add(obj);
        }
        try {
            EasyExcelUtil.writeExcel(response, datalist, headList, fileName, fileName);
        } catch (IOException e) {
            log.error("{}导出异常：", fileName, e);
            throw new UtilException("导出失败：" + e.getMessage());
        }
    }

    /**
     * @Description 待收款、已结算  - 修改备注
     * @Author yangxm
     * @Date 2025/6/25 14:45
     * @param handlingFee
     * @return int
     */
    @Override
    public int updateRemark(HandlingFee handlingFee) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser == null){
            throw new UtilException("登录已失效，请重新登录！");
        }
        handlingFee.setRemarkOperator(loginUser.getUsername());
        return serviceFeeMapper.updateRemark(handlingFee);
    }

    /**
     * @Description 待收款、已结算  - 详情 - 人员列表
     * @Author yangxm
     * @Date 2025/6/25 14:56
     * @param personDTO
     * @return java.util.List<com.qixiaobao.nondirect.invoice.domain.domain.Person>
     */
    @Override
    public List<Person> selectHandlingFeeDetailPersonList(PersonDTO personDTO) {
        return personMapper.selectChargePersonList(personDTO);
    }

    /**
     * @Description 手续费结算/一键结算，供应商校验
     * @Author yangxm
     * @Date 2025/6/24 14:22
     * @param supplyerList
     */
    private void checkSupply(List<Supply> supplyerList) {
        //供应商全称唯一校验
        List<String> supplyNameList = supplyerList.stream().map(Supply::getSupplyName).distinct().collect(Collectors.toList());
        if (supplyNameList.size() != 1){
            throw new IllegalArgumentException("不能包含多个供应商全称，请检查！");
        }
        //保费系数唯一校验
        List<BigDecimal> insureFeeFactorList = supplyerList.stream().map(Supply::getInsureFeeFactor).distinct().collect(Collectors.toList());
        if (insureFeeFactorList.size() != 1){
            throw new IllegalArgumentException("不能包含多个保费系数，请检查！");
        }
        //手续费税率唯一校验
        List<BigDecimal> serviceRateList = supplyerList.stream().map(Supply::getServiceRate).distinct().collect(Collectors.toList());
        if (serviceRateList.size() != 1){
            throw new IllegalArgumentException("不能包含多个手续费税率，请检查！");
        }
        //经纪结算费率唯一校验
        List<BigDecimal> brokerageSettleRatioList = supplyerList.stream().map(Supply::getBrokerageSettleRatio).distinct().collect(Collectors.toList());
        if (brokerageSettleRatioList.size() != 1){
            throw new IllegalArgumentException("不能包含多个经纪结算费，请检查！");
        }
        //手续费发票类型唯一校验
        List<String> procedureFeeInvoiceTypeList = supplyerList.stream().map(Supply::getProcedureFeeInvoiceType).distinct().collect(Collectors.toList());
        if (procedureFeeInvoiceTypeList.size() != 1){
            throw new IllegalArgumentException("不能包含多个手续费发票类型，请检查！");
        }
    }
}
